package pojo

import (
	"database/sql"
	"fmt"
	"fyne.io/fyne"
	"fyne.io/fyne/dialog"
	"strconv"
	"strings"
)

/**
自定的一个连接数据库的类
*/
//const SOURCE_FILE  ="./data/sourceData.txt"
const SOURCE_FILE = "D:\\2020CODE\\totest\\src\\data\\sourceData.txt"
const TEMPLATE_FILE = "D:\\2020CODE\\totest\\src\\data\\template.txt"

type DB = sql.DB
type DataSource struct {
	//用户名
	UserName string
	//密码
	Password string
	//数据库的名称
	DbName string
	//数据库的ip
	Ip string
	//数据库的端口号
	Port int
	//扩展
	Extend string
	//数据库类型 oracle/mysql
	DbType string
	Method DataSourceF `json:"-"`
}

type DataSourceF interface {
	CreateContentStr(source DataSource) (*DB, error)
}
type MysqlSource struct {
}
type OracleSource struct {
}

/**
是否成功创建连接
*/
func (ds *DataSource) CreateLink() (*DB, error, string) {
	reStr := ""
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println(err)
		}
		reStr = "123123213"
	}()
	db, ok := ds.Method.CreateContentStr(*ds)
	if ok != nil {
		fmt.Println("opon database fail")
		reStr = "opon database fail"
		return nil, ok, reStr
	}
	fmt.Println("connnect success")

	if db.Ping() != nil {
		reStr = "ping...fail"
		return nil, ok, reStr
	}
	fmt.Println("ping...ok")
	reStr = "connnect success"
	return db, ok, reStr
}

/**
返回字段的类型和名称
*/
func (ds *DataSource) GetColumn(sql string, w *fyne.Window) []JiuColumn {
	defer func() {
		er := recover()
		if er != nil {
			dialog.ShowInformation("sql运行失败", fmt.Sprint(er), *w)
			fmt.Println(er)
		}
	}()
	res := make([]JiuColumn, 0)
	db, ok, _ := ds.CreateLink()
	if ok != nil {
		dialog.ShowInformation("sql运行失败", fmt.Sprint(ok), *w)
		fmt.Println(ok)
		return res
	}
	rows, ok := db.Query(sql)
	if ok != nil {
		dialog.ShowInformation("sql运行失败", fmt.Sprint(ok), *w)

		fmt.Println(ok)
		return res
	}
	clTpye, ok := rows.ColumnTypes()
	if ok != nil {
		dialog.ShowInformation("sql运行失败", fmt.Sprint(ok), *w)

		fmt.Println(ok)
		return res
	}
	for _, v := range clTpye {
		res = append(res, JiuColumn{
			Column:     v.Name(),
			ColumnType: v.DatabaseTypeName(),
			CamelCase:  ToCamelCase(v.Name()),
		})
	}
	db.Close()
	return res
}

////构建连接："用户名:密码@tcp(IP:端口)/数据库?charset=utf8"
func (ds *MysqlSource) CreateContentStr(source DataSource) (*DB, error) {
	str := []string{source.UserName, ":", source.Password, "@tcp(", source.Ip, ":", strconv.Itoa(source.Port), ")/", source.DbName, source.Extend}
	fmt.Println("running mysql")
	return sql.Open("mysql", strings.Join(str, ""))
}

// sql.Open("godror", `user="scott" password="tiger" connectString="dbhost:1521/orclpdb1"`)
func (ds *OracleSource) CreateContentStr(source DataSource) (*DB, error) {
	str := fmt.Sprintf("user=%v password=%v connectString=%v:%v/%v", source.UserName, source.Password, source.Ip, source.Port, source.DbName)
	fmt.Println("running oracle")
	return sql.Open("godror", str)
}

func GetColumn(userName, password, dbName, ip string, port int, dbType, extend string) []JiuColumn {
	var _dbType DataSourceF
	var rest []JiuColumn
	switch dbType {
	case "mysql":
		_dbType = new(MysqlSource)
	case "oracle":
		_dbType = new(OracleSource)
	}
	/*dataSource := DataSource{
		UserName: userName,
		Password: password,
		DbName:   dbName,
		Ip:       ip,
		Port:     port,
		Extend:   extend,
		Method:   _dbType,
	}*/
	fmt.Println(_dbType)
	return rest

}
